import Phaser, { Time } from "phaser";
import { QUIView, QUIEvent } from "phaser-qgame/dist/QUIView";
import { QUILabel } from "phaser-qgame/dist/QUILabel";
import { QUIInput } from "phaser-qgame/dist/QUIInput";

import { ProjectChange } from "../../component/ProjectMange";

export default class Layout extends Phaser.Scene {
    // public viewList: Array<QUIView> = [];
    public rootView: QUIView | null;
    public placeView: QUIView | null = null;
    // public placeViewDrag: boolean = false;
    public editorView: QUIView | null = null;
    public parentView: QUIView | null = null;
    private rect: Phaser.GameObjects.Graphics;

    private historicalRecords: Array<String> = [];

    private clipView: QUIView | null = null;
    private clipText: string = "";

    constructor() {
        super("Layout");
        window["layout"] = this;
    }

    draw() {
        if (this.editorView) {
            this.rect.clear();
            const x = this.editorView.WorldX;
            const y = this.editorView.WorldY;
            const width = this.editorView.Width;
            const height = this.editorView.Height;
            this.rect.lineStyle(2, 0xff0000);
            this.rect.strokeRect(x, y, width, height);
        }
    }

    preload() {}

    addOptionRecord() {
        const xmlstr = this.getXML();
        if (xmlstr) {
            this.historicalRecords.push(xmlstr);
        }
    }

    selectd(uuid: string) {
        this.editorView = this.qGame.findViewByUUID(uuid);
        if (this.editorView == null) {
            this.editorView = this.rootView;
        }
        // this.downX = pointer.x - this.editorView.WorldX;
        // this.downY = pointer.y - this.editorView.WorldY;
        // console.log(this.downX, this.downY);
        // this.downTime = Date.now();
        this.onSelectView();
    }

    /** 选中组件 */
    onSelectView() {
        if (this.editorView && window["onSelectComponent"]) {
            window["onSelectComponent"](
                this.editorView.getViewAttribute(),
                this.editorView.Name
            );
        }

        this.draw();
    }

    onMove() {
        this.draw();
    }

    loadImage(imageList: [], callback: () => null) {
        console.log("load image");
        // this.load.setBaseURL("http://127.0.0.1:3336/asset/");
        for (let i = 0; i < imageList.length; i++) {
            const fileInfo = imageList[i];
            if (!this.textures.exists(fileInfo["relative"])) {
                // console.log("load", "/" + fileInfo["relative"]);
                // console.log(
                //     "http://127.0.0.1:3336/asset/" + fileInfo["relative"]
                // );
                this.load.image(fileInfo["relative"], fileInfo["relative"]);
                // this.load.addFile()
            }
        }

        this.load.start();
        this.load.on("complete", () => {
            if (callback) {
                callback();
            }
            console.log("load comple");
        });
    }

    // 设置项目的URL
    setProjectUrl(projectUrl: string) {
        console.log("set project url", projectUrl);
        this.load.setBaseURL(projectUrl);
    }

    cut() {
        if (
            this.editorView &&
            this.editorView != this.rootView &&
            this.editorView.Parent
        ) {
            const xml = this.editorView.convertToXML();
            const xmlString = new XMLSerializer().serializeToString(xml);
            this.clipText = xmlString;
            this.editorView.Parent.remove(this.editorView, true);
            this.renderingTree();
            if (this.rootView) {
                window["selectd"](this.rootView.UUID);
            }
            // this.draw();
            this.rect.clear();
        }
    }

    copy() {
        if (
            this.editorView &&
            this.editorView != this.rootView &&
            this.editorView.Parent
        ) {
            const xml = this.editorView.convertToXML();
            const xmlString = new XMLSerializer().serializeToString(xml);
            this.clipText = xmlString;
        }
    }

    paste() {
        if (this.editorView) {
            if (this.clipText != "") {
                const view = this.qGame.add.objectFromXML(this.clipText);
                console.log(view);
                if (view) {
                    this.editorView.add(view);
                    this.renderingTree();
                    if (this.rootView) {
                        window["selectd"](this.rootView.UUID);
                    }
                    ProjectChange();
                }
            }
        }
    }

    setAttribute(key: string, value: any) {
        if (this.editorView === null) {
            return;
        }
        ProjectChange();
        switch (key) {
            case "id":
                this.editorView.Id = value;
                this.renderingTree();
                window["selectd"](this.editorView.UUID);

                break;
            case "class":
                this.editorView.Class = value;
                this.renderingTree();
                window["selectd"](this.editorView.UUID);

                break;
            case "widthRatio":
                this.editorView.WidthRatio = value;
                break;
            case "heightRatio":
                this.editorView.HeightRatio = value;
                break;
            case "width":
                this.editorView.Width = value;
                break;
            case "height":
                this.editorView.Height = value;
                break;
            case "miniWidth":
                this.editorView.MiniWidth = value;
                break;
            case "miniHeight":
                this.editorView.MiniHeight = value;
                break;
            case "maxWidth":
                this.editorView.MaxWidth = value;
                break;
            case "maxHeight":
                this.editorView.MaxHeight = value;
                break;
            case "left":
                if (
                    this.editorView.Parent &&
                    (this.editorView.Parent.Name == "QUIVerticalLayout" ||
                        this.editorView.Parent.Name == "QUIHorizontalLayout" ||
                        this.editorView.Parent.Name == "QUIGridLayout" ||
                        this.editorView.Parent.Name == "QUICanvas")
                ) {
                    break;
                }
                this.editorView.Left = value;

                break;
            case "top":
                if (
                    this.editorView.Parent &&
                    (this.editorView.Parent.Name == "QUIVerticalLayout" ||
                        this.editorView.Parent.Name == "QUIHorizontalLayout" ||
                        this.editorView.Parent.Name == "QUIGridLayout" ||
                        this.editorView.Parent.Name == "QUICanvas")
                ) {
                    break;
                }
                this.editorView.Top = value;
                this.editorView.Background = this.editorView.Background;
                break;
            case "right":
                if (
                    this.editorView.Parent &&
                    (this.editorView.Parent.Name == "QUIVerticalLayout" ||
                        this.editorView.Parent.Name == "QUIHorizontalLayout" ||
                        this.editorView.Parent.Name == "QUIGridLayout" ||
                        this.editorView.Parent.Name == "QUICanvas")
                ) {
                    break;
                }
                this.editorView.Right = value;
                this.editorView.Background = this.editorView.Background;
                break;
            case "bottom":
                if (
                    this.editorView.Parent &&
                    (this.editorView.Parent.Name == "QUIVerticalLayout" ||
                        this.editorView.Parent.Name == "QUIHorizontalLayout" ||
                        this.editorView.Parent.Name == "QUIGridLayout" ||
                        this.editorView.Parent.Name == "QUICanvas")
                ) {
                    break;
                }
                this.editorView.Bottom = value;
                break;
            case "background":
                this.editorView.Background = value;
                break;
            case "alpha":
                this.editorView.Alpha = value / 100;
                break;
            case "borderWidth":
                this.editorView.BorderWidth = value;
                break;
            case "borderColor":
                this.editorView.BorderColor = value;
                break;
            case "alignY":
                this.editorView.AlignY = value;
                break;
            case "alignX":
                this.editorView.AlignX = value;
                break;
            case "gap":
                this.editorView.Gap = value;
                break;
            case "paddingTop":
                this.editorView.PaddingTop = value;
                break;
            case "paddingBottom":
                this.editorView.PaddingBottom = value;
                break;
            case "paddingLeft":
                this.editorView.PaddingLeft = value;
                break;
            case "paddingRight":
                this.editorView.PaddingRight = value;
                break;
            case "imageUrl":
                this.editorView.ImageUrl = value;
                break;
            case "text":
                if (
                    this.editorView.Name === "QUILabel" ||
                    this.editorView.Name === "QUIButton" ||
                    this.editorView.Name === "QUIInput"
                ) {
                    const lable = this.editorView as QUILabel;
                    lable.Text = value;
                }

                break;
            case "fontSize":
                if (
                    this.editorView.Name === "QUILabel" ||
                    this.editorView.Name === "QUIButton" ||
                    this.editorView.Name === "QUIInput"
                ) {
                    const lable = this.editorView as QUILabel;
                    lable.FontSize = value;
                    console.log("fontSize", lable.FontSize);
                }
                break;
            case "fontColor":
                if (
                    this.editorView.Name === "QUILabel" ||
                    this.editorView.Name === "QUIButton" ||
                    this.editorView.Name === "QUIInput"
                ) {
                    const lable = this.editorView as QUILabel;
                    lable.FontColor = value;
                }
                break;
            case "fontFamily":
                if (
                    this.editorView.Name === "QUILabel" ||
                    this.editorView.Name === "QUIButton" ||
                    this.editorView.Name === "QUIInput"
                ) {
                    const lable = this.editorView as QUILabel;
                    lable.FontFamily = value;
                }
                break;
            case "inputType":
                if (this.editorView.Name === "QUIInput") {
                    const input = this.editorView as QUIInput;
                    input.InputType = value;
                }
                break;
            case "placeholder":
                if (this.editorView.Name === "QUIInput") {
                    const input = this.editorView as QUIInput;
                    input.Placeholder = value;
                }
                break;
        }
        this.draw();
    }

    renderingTree() {
        window["renderingTree"](this.rootView);
    }

    move(moveIdx: number) {
        // this.selectd(uuid);
        console.log(moveIdx);
        if (this.editorView && this.editorView.Parent) {
            const idx = this.editorView.Parent.ChildViews.indexOf(
                this.editorView
            );
            // if (idx > 0 && idx < this.editorView.Parent.ChildViews.length - 1) {
            //     this.editorView.move(idx + moveIdx);
            //     ProjectChange();
            //     this.draw();
            // }
        }
    }

    delete() {
        if (this.editorView === this.rootView) {
            alert("不可以删除根节点");
            return;
        }
        if (this.editorView && confirm("确定删除该组件及子元素吗？")) {
            if (this.editorView.Parent) {
                this.editorView.Parent.remove(this.editorView, true);
            } else {
                this.editorView.destroy();
            }
            this.editorView = this.rootView;
            window["onDeleteComponent"]();
            this.renderingTree();
            this.draw();
        }
    }
    private isDown = false;

    create() {
        this.rect = this.add.graphics();
        this.rect.depth = 9000;

        this.rootView = this.qGame.add.view({
            id: "body",
            left: 10,
            top: 10,
            width: 600,
            height: 600,
            background: 0x404f40,
        });
        if (this.rootView === null) return;
        if (this.rootView) this.renderingTree();

        // const keyboard = this.input.keyboard;

        // if (keyboard) {
        //     keyboard.on("keydown", (event) => {
        //         if (event.key === "Delete") {
        //             this.delete();
        //         }
        //     });
        // }

        let clickX = 0;
        let clickY = 0;

        // 监听鼠标按下事件
        this.input.on("pointerdown", (pointer, objects) => {
            if (objects.length > 0) {
                let node = this.qGame.positionFindView(pointer.x, pointer.y);
                if (node) {
                    this.selectd(node.UUID);

                    window["selectd"](node.UUID);
                }
            } else {
                this.editorView = null;
                this.rect.clear();
                window["onCancelSelectComponent"]();
            }

            if (this.editorView) {
                clickX = pointer.x - this.editorView.WorldX;
                clickY = pointer.y - this.editorView.WorldY;
                this.isDown = true;
            }
        });

        // 监听鼠标抬起
        this.input.on("pointerup", (pointer, objects) => {
            this.isDown = false;

            if (this.editorView) {
                this.selectd(this.editorView.UUID);
                let x = pointer.x - this.editorView.WorldX;
                let y = pointer.y - this.editorView.WorldY;
                if (x != clickX || y != clickY) {
                    ProjectChange();
                }
            }
            clickX = 0;
            clickY = 0;
        });

        // 拖拽
        this.input.on("pointermove", (pointer) => {
            if (this.isDown && this.editorView) {
                // 判断鼠标是否在编辑视图内部
                if (this.editorView === this.rootView) return;
                if (
                    this.editorView.WorldX < pointer.x &&
                    pointer.x <
                        this.editorView.WorldX + this.editorView.Width &&
                    this.editorView.WorldY < pointer.y &&
                    pointer.y < this.editorView.Height + this.editorView.WorldY
                ) {
                    if (
                        this.editorView.Parent &&
                        this.editorView.Parent.Name != "QUIHorizontalLayout" &&
                        this.editorView.Parent.Name != "QUIVerticalLayout" &&
                        this.editorView.Parent.Name != "QUIGridLayout"
                    ) {
                        this.editorView.Left =
                            pointer.x - this.editorView.Parent.WorldX - clickX;
                        this.editorView.Top =
                            pointer.y - this.editorView.Parent.WorldY - clickY;
                        this.draw();
                    }
                }
            }
        });

        // 安装键盘事件监听
        // if (this.input.keyboard) {
        //     this.input.keyboard.on("keydown", (event) => {
        //         if (this.editorView) {
        //             if (event.key === "ArrowUp") {
        //                 this.editorView.Top -= 1;
        //             } else if (event.key === "ArrowDown") {
        //                 this.editorView.Top += 1;
        //             } else if (event.key === "ArrowLeft") {
        //                 this.editorView.Left -= 1;
        //             } else if (event.key === "ArrowRight") {
        //                 this.editorView.Left += 1;
        //             }
        //             this.draw();
        //         }
        //     });
        // }
    }

    keydown(event) {
        if (this.editorView) {
            if (event.key === "ArrowUp") {
                this.editorView.Top -= 1;
            } else if (event.key === "ArrowDown") {
                this.editorView.Top += 1;
            } else if (event.key === "ArrowLeft") {
                this.editorView.Left -= 1;
            } else if (event.key === "ArrowRight") {
                this.editorView.Left += 1;
            } else if (event.key === "Escape") {
                this.isDown = false;
            }

            this.draw();
        }
    }

    loadXML(xmlstr: string) {
        // const xml = new DOMParser().parseFromString(xmlstr, "text/xml");
        // <view width="600" height="400" top="0" left="0" background="#ffB5F6"></view>
        // this.qGame.loadQML("test", xmlstr, (key, type, data) => {
        //     console.log(key, type, data);
        // });
        if (this.rootView) {
            this.rootView.destroy();
        }

        this.editorView = null;

        const view = this.qGame.add.objectFromXML(xmlstr);
        if (view) {
            this.qGame.add.Nodes.forEach((node) => {
                if (node.Name == "QUIInput") {
                    const input = node as QUIInput;
                    input.closeInput();
                }
            });

            this.rootView = view;
            this.editorView = this.rootView;
            this.renderingTree();
        }
    }

    getXML() {
        if (this.rootView) {
            const dom = this.rootView.convertToXML();
            const xmlString = new XMLSerializer().serializeToString(dom);
            console.log(xmlString);
            return xmlString;
        }
        return "";
    }

    getRandomHexColor() {
        return (
            "0x" +
            Math.floor(Math.random() * 16777215)
                .toString(16)
                .padStart(6, "0")
        );
    }
    addView(): QUIView | null {
        if (this.rootView === null) return null;
        const view = this.qGame.add.view({
            id: "view_" + this.qGame.add.Nodes.length + 1,
            left: 0,
            top: 0,
            width: 200,
            height: 200,
            alpha: 1,
            background: this.getRandomHexColor(),
        });
        if (view === null) {
            return null;
        }

        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
        return view;
    }

    addLabel() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.label({
            id: "label_" + this.qGame.add.Nodes.length + 1,
            left: 0,
            top: 0,
            text: "Label",
            fontFamily: "Arial",
            fontSize: 12,
            fontColor: "#808080",
        });
        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
    }

    /** 垂直布局 */
    addVertical() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.verticalLayout({
            id: "vertical_" + this.qGame.add.Nodes.length + 1,
            background: "#ffffff",
            aplpha: 0.5,
            heightRatio: 100,
            width: 100,
            left: 0,
            top: 0,
        });

        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
        return view;
    }
    /** 水平布局 */
    addHertical() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.horizontalLayout({
            id: "horizontal_" + this.qGame.add.Nodes.length + 1,
            background: "#5fff5f",
            aplpha: 0.5,
            widthRatio: 100,
            height: 100,
            width: 200,
            left: 0,
            top: 0,
        });
        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
    }

    addGrid() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.gridLayout({
            id: "grid_" + this.qGame.add.Nodes.length + 1,
            background: "#5f5fff",
            aplpha: 0.5,
            widthRatio: 100,
            heightRatio: 100,
            left: 0,
            top: 0,
        });
        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
    }

    addScroll() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.scroll({
            id: "scroll_" + this.qGame.add.Nodes.length + 1,
            background: "#000000",
            alpha: 0.5,
            widthRatio: 100,
            heightRatio: 100,
            left: 0,
            top: 0,
        });
        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
    }

    addButton() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.button({
            id: "button_" + this.qGame.add.Nodes.length + 1,
            alpha: 1,
        });
        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
    }

    addInput() {
        if (this.rootView === null) return null;
        const view = this.qGame.add.input({
            id: "input_" + this.qGame.add.Nodes.length + 1,
            placeholder: "请输入内容",
            alpha: 1,
        });
        if (view === null) return;
        if (this.editorView) {
            this.editorView.add(view);
        } else {
            this.rootView.add(view);
        }
        this.renderingTree();
    }

    update() {}
}
